package cn.buyclss.backend.controller;

import cn.buyclss.backend.annotation.SysLog;
import cn.buyclss.backend.async.MailTask;
import cn.buyclss.backend.entity.domain.User;
import cn.buyclss.backend.entity.po.UserPO;
import cn.buyclss.backend.entity.support.RespResult;
import cn.buyclss.backend.entity.vo.EmailVO;
import cn.buyclss.backend.entity.vo.LoginUserVO;
import cn.buyclss.backend.entity.vo.RegisterUserVO;
import cn.buyclss.backend.service.UserService;
import cn.buyclss.backend.service.support.QiniuService;
import cn.buyclss.backend.util.CheckUtils;
import cn.buyclss.backend.util.JWTUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;

/**
 * @author: Cecurio
 * @create: 2019-02-10 14:37
 **/
@RestController
@Api(value = "基础控制器", description = "基础控制器")
public class IndexController {

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private TaskExecutor taskExecutor;


    @Autowired
    private QiniuService qiniuService;

    /**
     * 七牛云存放图片的根路径
     */
    @Value("${qiniu.image_url}")
    private String qiniuImageURL;


    @SysLog("登录系统")
    @PostMapping("/login")
    @ApiOperation(value = "登录")
    public RespResult login(@RequestBody LoginUserVO userVO) {
        User user = userService.getUserByUsernameAndPassword(userVO.getUserName(), userVO.getPassWord());
        RespResult res = null;
        if (user != null) {
            res = RespResult.successInstance();
            res.putValue("token", JWTUtil.sign(user.getId(), user.getUserName(), user.getType()));
            return res;
        }
        res = RespResult.failureInstance("用户名/密码错误");
        return res;
    }

    @SysLog("注册账号")
    @PostMapping("/register")
    @ApiOperation(value = "注册", notes = "先获取邮箱验证码再注册")
    public RespResult register(@RequestBody RegisterUserVO userVO) {
        return userService.addOne(userVO);
    }


    @PostMapping("/sendYzmToMail")
    @ApiOperation("发送验证码到邮箱")
    public RespResult sendYzmToEmail(@RequestBody EmailVO emailVO) {
        if (!CheckUtils.validEmail(emailVO.getEmail())) {
            return RespResult.failureInstance("邮箱格式不正确！");
        }
        taskExecutor.execute(new MailTask("b2bc", emailVO.getEmail(), javaMailSender));
        return RespResult.successInstance();
    }

    @SysLog("查看个人信息")
    @GetMapping("/userInfo")
    @RequiresAuthentication
    @ExceptionHandler({UnauthorizedException.class})
    @ApiImplicitParam(paramType = "header", name = "Authorization", required = true, value = "${IndexController.username.header.authorization}")
    public RespResult username() {
        RespResult res = null;
        Subject subject = SecurityUtils.getSubject();
        Object obj = subject.getPrincipal();

        if (obj instanceof User) {
            res = RespResult.successInstance();
            User u = (User) obj;
            UserPO userPO = new UserPO();
            userPO.setId(u.getId());
            userPO.setUserName(u.getUserName());
            userPO.setType(u.getType());
            userPO.setHasShop(u.getHasShop());
            userPO.setLogoUrl(u.getLogoUrl());
            userPO.setBirthday(u.getBirthday());
            userPO.setGender(u.getGender());
            userPO.setEmail(u.getEmail());
            userPO.setPhone(u.getPhone());
            userPO.setAcademyId(u.getAcademyId());
            userPO.setClassId(u.getClassId());
            res.putValue("userInfo", userPO);
            return res;
        }
        res = RespResult.failureInstance("失败");
        return res;
    }


    //上传图片
    @PostMapping(value = "/upload")
    @RequiresAuthentication
    @ApiOperation(value = "上传文件", notes = "支持的类型有：image/bmp, image/gif, image/jpeg, image/png \\t , 大小小于3M")
    @ApiImplicitParam(paramType = "header", name = "Authorization", required = true)
    public RespResult upload(MultipartFile myFileName) throws IOException {

        // 文件类型限制
        String[] allowedType = {"image/bmp", "image/gif", "image/jpeg", "image/png"};
        boolean allowed = Arrays.asList(allowedType).contains(myFileName.getContentType());

        RespResult res = RespResult.failureInstance("");
        if (!allowed) {
            res.setErrMsg("error|不支持的类型");
            return res;
        }
        // 图片大小限制
        if (myFileName.getSize() > 3 * 1024 * 1024) {
            res.setErrMsg("error|图片大小不能超过3M");
            return res;
        }
        // 包含原始文件名的字符串
        String fi = myFileName.getOriginalFilename();
        // 提取文件拓展名
        String fileNameExtension = fi.substring(fi.indexOf("."), fi.length());
        // 生成云端的真实文件名
        String remoteFileName = UUID.randomUUID().toString() + fileNameExtension;

        qiniuService.upload(myFileName.getBytes(), remoteFileName);

        // 返回图片的URL地址
        res = RespResult.successInstance();
        res.putValue("imageUrl", qiniuImageURL + remoteFileName);
        return res;
    }

    @GetMapping(path = "/401")
    public RespResult unauthorized() {
        return RespResult.failureInstance("令牌(token)过期 或者 访问权限不够");
    }

    //    @GetMapping("/index")
//    @ApiOperation(value = "查看首页")
//    @RequiredPermission("首页")
//    public Map<String, Object> index() {
//        redisTemplate.opsForValue().set("JWT-SESSION-" + "100001",
//            "abcdefghjikll",
//            120, TimeUnit.SECONDS);
//        logger.info("==enter index router==");
//        Map<String, Object> res = new HashMap<>();
//        res.put("title", "首页");
//        res.put("description", "描述");
//        return res;
//    }

    //    @GetMapping("/admin/center")
//    @ApiOperation(value = "查看管理员界面")
//    @RequiredPermission("管理员")
//    public RespResult admin() {
//        RespResult res = new RespResult();
//        res.setCode(0);
//        res.setErrMsg("");
//        Map<String, Object> map = new HashMap<>();
//        map.put("title", "管理员界面");
//        map.put("description", "管理员才可以查看");
//        res.setData(map);
//        return res;
//    }
}
